package cn.bird.storm.component.jackson.serialize;

import cn.bird.storm.component.jackson.annotation.BigDecimalSerializeAnnotation;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

@Data
@EqualsAndHashCode(callSuper = false)
public class BigDecimalCustomizeSerialize extends JsonSerializer<BigDecimal> implements ContextualSerializer {
    /**
     * 是否要处理小数位
     */
    private boolean handleScale;
    /**
     * 保留小数位数 默认2位
     * 要处理小数位的时候才会执行
     */
    private int scale;
    /**
     * 要除以的某数
     */
    private String divide;
    /**
     * 要乘以的某数
     */
    private String multiply;
    /**
     * 结果后置符号
     */
    private String afterSymbol;

    /**
     * 结果前置符号
     */
    private String beforeSymbol;
    /**
     * 多余小数省略策略
     */
    private RoundingMode roundingMode;


    @Override
    public void serialize(BigDecimal bigDecimal, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
        if (StrUtil.isNotBlank(multiply) && NumberUtil.isNumber(multiply)) {
            bigDecimal = bigDecimal.multiply(new BigDecimal(multiply));
        }
        if (StrUtil.isNotBlank(divide) && NumberUtil.isNumber(divide)) {
            BigDecimal divided = new BigDecimal(divide);
            if (BigDecimal.ZERO.compareTo(divided) != 0) {
                bigDecimal = bigDecimal.divide(divided);
            }
        }
        if (handleScale) {
            bigDecimal = bigDecimal.setScale(scale, roundingMode);
        }
        jsonGenerator.writeString(beforeSymbol + bigDecimal.toString() + afterSymbol);
    }
    /**
     * 定制序列化器
     */
    @Override
    public JsonSerializer<?> createContextual(SerializerProvider serializerProvider, BeanProperty beanProperty) throws JsonMappingException {
        // 为空直接跳过
        if (beanProperty != null) {
            // 非 BigDecimal 类直接跳过
            if (Objects.equals(beanProperty.getType().getRawClass(), BigDecimal.class)) {
                BigDecimalSerializeAnnotation annotation = beanProperty.getAnnotation(BigDecimalSerializeAnnotation.class);
                if (annotation == null) {
                    annotation = beanProperty.getContextAnnotation(BigDecimalSerializeAnnotation.class);
                }
                if (annotation != null) {
                    BigDecimalCustomizeSerialize bigDecimalCustomizeSerialize = new BigDecimalCustomizeSerialize();
                    bigDecimalCustomizeSerialize.setHandleScale(annotation.handleScale());
                    bigDecimalCustomizeSerialize.setScale(annotation.scale());
                    bigDecimalCustomizeSerialize.setDivide(annotation.divide());
                    bigDecimalCustomizeSerialize.setMultiply(annotation.multiply());
                    bigDecimalCustomizeSerialize.setAfterSymbol(annotation.afterSymbol());
                    bigDecimalCustomizeSerialize.setBeforeSymbol(annotation.beforeSymbol());
                    bigDecimalCustomizeSerialize.setRoundingMode(annotation.roundingMode());
                    return bigDecimalCustomizeSerialize;
                }
            }
            return serializerProvider.findValueSerializer(beanProperty.getType(), beanProperty);
        }
        return serializerProvider.findNullValueSerializer(null);
    }

}
